/**
 * ServerWebSocket is implements the WebSocket function of server side.
 * @version 1.0.0 01/20/2012
 * @author Yanqing Liu
 *
 */

package edu.baylor.websocket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * ServerWebSocket implements WebSocket server
 * @version 1.0.0 01/28/2012
 * @author Yanqing Liu
 */
public class ServerWebSocket {
    private ServerSocket servSock; //TCP server socket
    private Socket clntSock;
    private WebSocket webSocket;
    Integer timeout = 0;
    
    /**
     * Create ServerWebSocket from specific tcp port
     * @param port 
     *      tcp port used by WebSocket server to communicate
     * @param timeout 
     *      maximum time for handshake
     * @throws IOException
     *      when there is a problem with tcp connection
     */
    public ServerWebSocket(Integer port, Integer timeout) 
            throws IOException {
        servSock = new ServerSocket(port);
        this.timeout = timeout;
    }
    
    /**
     * Accept the request from client
     * @throws IOException
     *      when there is a problem with tcp connection
     */
    public WebSocket accept() throws IOException {
    
        clntSock = servSock.accept();

        HandShaker handShaker = new HandShaker(clntSock.getInputStream(),
                                        clntSock.getOutputStream());
    
        FutureTask<Object> ft = new FutureTask<Object>(handShaker, 
                        null);
        try {
            (new Thread(ft)).start();
            if (timeout > 0) {
                ft.get(timeout, TimeUnit.MILLISECONDS);
            } else {
                ft.get();
            }
        } catch (Exception e) {
            clntSock.close();
            throw new IOException("Handshake failed", e);
        }
        
        if (handShaker.getException() != null) {
            clntSock.close();
            throw new IOException("Handshake failed", 
                    handShaker.getException());
        }

        webSocket = new WebSocket(clntSock);

        return webSocket;
    }
    
    /**
     * Close the connection 
     * @throws IOException
     *      when there is a problem with tcp connection
     */
    public void close()throws IOException {
        servSock.close();
    }
}
